/**
 * 项目名：化工企业安全生产信息化管理平台
 * 日期：    2020-03-01 22:19:08
 * Copyright (c) 2015- -版权所有
 */

package com.joysuch.wwyt.edu.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.poi.word.Word07Writer;
import com.alibaba.fastjson.JSONArray;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.joysuch.wwyt.common.constant.Constant;
import com.joysuch.wwyt.common.entity.CommonType;
import com.joysuch.wwyt.common.enums.CommonTypes;
import com.joysuch.wwyt.common.service.CommonTypeService;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.common.util.PageDataUtils.PageDataConvert;
import com.joysuch.wwyt.core.exception.BusinessRestrictionsException;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.edu.bean.*;
import com.joysuch.wwyt.edu.bean.EduTestPaperListBean.SearchEduTestPaper;
import com.joysuch.wwyt.edu.entity.EduQuestion;
import com.joysuch.wwyt.edu.entity.EduQuestionItem;
import com.joysuch.wwyt.edu.entity.EduTestPaper;
import com.joysuch.wwyt.edu.entity.EduTestPaperQuestion;
import com.joysuch.wwyt.edu.entity.dsl.QEduExamTestPaper;
import com.joysuch.wwyt.edu.entity.dsl.QEduTestPaper;
import com.joysuch.wwyt.edu.enums.DistributionQuestionTypes;
import com.joysuch.wwyt.edu.enums.QuestionTypes;
import com.joysuch.wwyt.edu.mapper.EduTestPaperMapper;
import com.joysuch.wwyt.edu.repository.*;
import com.joysuch.wwyt.edu.service.EduQuestionService;
import com.joysuch.wwyt.edu.service.EduTestPaperQuestionService;
import com.joysuch.wwyt.edu.service.EduTestPaperService;
import com.joysuch.wwyt.edu.service.impl.EduQuestionServiceImpl.QuestionSelectWrapper;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import lombok.SneakyThrows;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.util.Assert;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.swing.*;
import javax.transaction.Transactional;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.net.URLEncoder;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Service
@Transactional
public class EduTestPaperServiceImpl implements EduTestPaperService {

    private static final Logger logger = LoggerFactory.getLogger(EduTestPaperServiceImpl.class);

    @Autowired
    private EduTestPaperDao dao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;
    @Autowired
    private BaseUserDao baseUserDao;
    @Autowired
    private EduTestPaperQuestionDao eduTestPaperQuestionDao;
    @Autowired
    private EduExamTestPaperDao eduExamTestPaperDao;
    @Autowired
    private CommonTypeService commonTypeService;
    @Autowired
    private EduTestPaperQuestionService eduTestPaperQuestionService;
    @Autowired
    private EduQuestionDao eduQuestionDao;
    @Autowired
    private EduQuestionDao questionDao;
    @Autowired
    private EduQuestionItemDao questionItemDao;
    @Autowired
    private EduQuestionService questionService;
    @Autowired
    private EduTestPaperDao eduTestPaperDao;
    @Autowired
    private EduTestPaperMapper eduTestPaperMapper;


    @Override
    public EduTestPaper add(EduTestPaperEditBean entity) {
        if (eduTestPaperMapper.selectByName(entity.getName())>0){
               throw new IllegalArgumentException("试卷名称已存在");
        }
        if (isRandomMode(entity.getCreateMode())) {
            validateConfigRules(entity.getConfigs());
        }
        String name = commonTypeService.getNameById(entity.getTypeId());
        if (StringUtils.isBlank(name)) {
            Assert.isTrue(false, "试卷类型未找到");
        }
        EduTestPaper content = new EduTestPaper();
        BeanUtils.copyProperties(entity, content, "id", "code");
        if (StringUtils.isNotBlank(entity.getCode())) {
            Assert.isTrue(dao.countOfCode(entity.getCode()) == 0, String.format("编号%s已经存在", entity.getCode()));
            content.setCode(entity.getCode());
        } else {
            content.setCode(bizCodeGeneratorFacade.shiJuan());
        }
        if (entity.getCreateUserName() == null) {
            content.setCreateUserName(baseUserDao.getBaseUserNameById(Context.getCurrentUserId()));
        }
        content.setState((byte) 0);
        content.setQuestionCount(entity.getQuestions() == null ? 0 : entity.getQuestions().size());
        content.setCreateMode(entity.getCreateMode());
        if (isRandomMode(entity.getCreateMode()) && entity.getConfigs() != null) {
            content.setCreateConfig(new Gson().toJson(entity.getConfigs()));
        }
        dao.save(content);
        if (isRandomMode(entity.getCreateMode()) && entity.getConfigs() != null
                && (entity.getQuestions() == null || entity.getQuestions().isEmpty())) {
            // 随机生成问卷，且没有在页面上选择题目
            List<QuestionSelectWrapper> questions = questionService.randomSelectWrapper(entity.getConfigs());
            content.setQuestionCount(questions.size());
            saveQuestions(content.getId(), questions);
        } else {
            saveQuestions(content.getId(), entity.getQuestions(), true);
        }
        if (content.getTypeId() != null) {
            commonTypeService.updateTypeCount(CommonTypes.TEST_PAPER, entity.getTypeId());
        }
        return content;
    }

    boolean isRandomMode(String mode) {
        return StringUtils.isNotBlank(mode) && "random".equals(mode);
    }

    private void saveQuestions(Long id, List<EduTestPaperQuestionEditBean> questions, boolean add) {
        if (questions == null || questions.isEmpty()) {
            return;
        }
        List<EduTestPaperQuestion> list = new ArrayList<>(questions.size());
        List<Long> keepIds = new ArrayList<>();
        int index = 0;
        // 如下修改逻辑允许同一题出现多次，如果不允许出现多次，需要按照questionid去重
        for (EduTestPaperQuestionEditBean q : questions) {
            if (q.getId() == null) {
                EduTestPaperQuestion question = new EduTestPaperQuestion();
                question.setQuestionId(q.getQuestionId());
                question.setScore(q.getScore());
                question.setTestPaperId(id);
                question.setIndexNo(index++);
                list.add(question);
            } else {
                EduTestPaperQuestion one = eduTestPaperQuestionDao.getOne(q.getId());
                one.setScore(q.getScore());
                one.setIndexNo(index++);
                list.add(one);
                keepIds.add(q.getId());
            }
        }
        if (!add) {
            // 编辑时，删除其他试卷
            if (keepIds.size() > 0) {
                eduTestPaperQuestionDao.clearRemovedItems(id, keepIds);
            } else {
                eduTestPaperQuestionDao.clearRemovedItems(id);
            }
        }
        eduTestPaperQuestionDao.saveAll(list);
    }

    private void saveQuestions(Long id, List<QuestionSelectWrapper> questions) {
        if (questions == null || questions.isEmpty()) {
            return;
        }
        List<EduTestPaperQuestion> list = new ArrayList<>(questions.size());
        int index = 0;
        // 如下修改逻辑允许同一题出现多次，如果不允许出现多次，需要按照questionid去重
        for (QuestionSelectWrapper q : questions) {
            EduTestPaperQuestion question = new EduTestPaperQuestion();
            question.setQuestionId(q.q.getId());
            question.setScore(q.config.getScore().doubleValue());
            question.setTestPaperId(id);
            question.setIndexNo(index++);
            list.add(question);
        }
        eduTestPaperQuestionDao.saveAll(list);
    }

    @Override
    public void update(EduTestPaperEditBean entity) {
        if (isRandomMode(entity.getCreateMode())) {
            validateConfigRules(entity.getConfigs());
        }
        Integer oldQuestionCount = 0;
        EduTestPaper content = dao.findById(entity.getId()).get();
        int num = eduExamTestPaperDao.countByPaperId(entity.getId());
        if (num > 0) {
            throw new IllegalArgumentException("该试卷已关联考试，不能修改");
//            if (entity.getCreateMode() != null && !entity.getCreateMode().equals(content.getCreateMode())) {
//                throw new IllegalArgumentException("该试卷已关联考试，不能修改试题");
//            }
//            if ("manual".equals(entity.getCreateMode()) && entity.getQuestions() != null && !checkQuesTion(entity.getQuestions(), content.getId())) {
//                throw new IllegalArgumentException("该试卷已关联考试，不能修改试题");
//            }
//            if ("random".equals(entity.getCreateMode()) && content.getCreateConfig() != null && !content.getCreateConfig().equals(new Gson().toJson(entity.getConfigs()))) {
//                throw new IllegalArgumentException("该试卷已关联考试，不能修改试题");
//            }
//            if (!entity.getPassScore().equals(content.getPassScore())){
//                throw new IllegalArgumentException("该试卷已关联考试，不能修改合格分数");
//            }
//            if (!entity.getTotalScore().equals(content.getTotalScore())){
//                throw new IllegalArgumentException("该试卷已关联考试，不能修改总数");
//            }
        }

        oldQuestionCount = content.getQuestionCount();
        // Assert.notNull(entity.getCode(), "编号不能为空");
        // Assert.isTrue(dao.countOfCodeExcludeId(entity.getCode(), entity.getId()) == 0,
        // String.format("编号%s已经存在", entity.getCode()));
        // content.setCode(entity.getCode());
        Long newTypeId = entity.getTypeId();
        Long oldTypeId = content.getTypeId();
        BeanUtils.copyProperties(entity, content, "id", "code");
        if (isRandomMode(entity.getCreateMode())) {
            content.setCreateConfig(entity.getConfigs() != null ? new Gson().toJson(entity.getConfigs()) : null);
        }
        // 随机模式
        if (isRandomMode(entity.getCreateMode())) {
            List<EduRandomSelectQuestionConfig> configs = entity.getConfigs();
            int count = 0;
            if (CollectionUtils.isNotEmpty(configs)) {
                count = configs.stream().mapToInt(EduRandomSelectQuestionConfig::getQuestionCount).sum();
            }
            content.setQuestionCount(count);
        } else {
            content.setQuestionCount(entity.getQuestions() == null ? 0 : entity.getQuestions().size());
        }
        dao.save(content);
        // 随机模式编辑了配置的情况下，更新题目，否则不更新
        if (isRandomMode(entity.getCreateMode()) && (entity.isConfigEdited() || entity.isChangedQuestion())) {
            // 配置发生了变化，分为2种情况，一种是在页面上选择了题目，另一种是未选择题目
            if (entity.isChangedQuestion()) {
                // 页面上重新生成了题目，保存这些题目
                saveQuestions(entity.getId(), entity.getQuestions(), false);
            } else {
                // 没有编辑题目，重新生成试题
                logger.info("试卷#{}随机模式编辑了配置，未在页面生成试题，重新生成", content.getId());
                List<QuestionSelectWrapper> questions = questionService.randomSelectWrapper(entity.getConfigs());
                eduTestPaperQuestionDao.deleteByTestPaperId(content.getId());
                saveQuestions(content.getId(), questions);
            }
        } else if (!isRandomMode(entity.getCreateMode())) {
            saveQuestions(entity.getId(), entity.getQuestions(), false);
        }
        if (!Objects.equals(newTypeId, oldTypeId)) {
            commonTypeService.updateTypeCount(CommonTypes.TEST_PAPER, newTypeId);
            commonTypeService.updateTypeCount(CommonTypes.TEST_PAPER, oldTypeId);
        }
    }


    boolean checkQuesTion(List<EduTestPaperQuestionEditBean> questions, Long paperId) {
        List<Long> list = eduTestPaperQuestionDao.findQidByPaperId(paperId);
        List<Long> ids = questions.stream().map(EduTestPaperQuestionEditBean::getQuestionId).collect(Collectors.toList());

        return list.size() > ids.size() ? ids.containsAll(list) : list.containsAll(ids);
    }

    @Override
    public Page<EduTestPaperListBean> findByPage(Pageable page, SearchEduTestPaper condition) {
        Predicate predicate = prepareListSearchCondition(condition);

        Page<EduTestPaper> data = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);

        return PageDataUtils.convertPageData(data, new PageDataConvert<EduTestPaperListBean, EduTestPaper>() {

            @Override
            public EduTestPaperListBean convert(EduTestPaper f) {
                EduTestPaperListBean bean = new EduTestPaperListBean();
                BeanUtils.copyProperties(f, bean);
                if (checkTestPaperContainZgt(f)) {
                    bean.setIsSupervisorQuestion(1);
                } else {
                    bean.setIsSupervisorQuestion(0);
                }

                bean.setTypeName(commonTypeService.getNameById(f.getTypeId()));
                // bean.setQuestionCount(dao.countOfQuestion(f.getId()));
                return bean;
            }

        });
    }

    @Override
    public Page<EduTestPaperListBean> findByWebPage(Pageable page, SearchEduTestPaper condition) {
         Predicate predicate = prepareListSearchCondition(condition);

        Page<EduTestPaper> data = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);
         return PageDataUtils.convertPageData(data, new PageDataConvert<EduTestPaperListBean, EduTestPaper>() {

            @Override
            public EduTestPaperListBean convert(EduTestPaper f) {
                EduTestPaperListBean bean = new EduTestPaperListBean();
                BeanUtils.copyProperties(f, bean);
                bean.setTypeName(commonTypeService.getNameById(f.getTypeId()));
                // bean.setQuestionCount(dao.countOfQuestion(f.getId()));
                return bean;
            }

        });
    }

    private Predicate prepareListSearchCondition(SearchEduTestPaper condition) {
        Predicate p = null;
        QEduTestPaper q = QEduTestPaper.eduTestPaper;
        if (condition.getNameOrCode() != null) {
            p = ExpressionUtils.or(q.name.contains(condition.getNameOrCode()),
                    q.code.contains(condition.getNameOrCode()));
        }
        if (condition.getTypeId() != null) {
            p = ExpressionUtils.and(p, q.typeId.eq(condition.getTypeId()));
        }
        return p;
    }


    @Override
    public Boolean checkTestPaperContainZgt(EduTestPaper testPaper) {
        boolean isZg = false;
        if (StringUtils.isNotBlank(testPaper.getCreateMode()) && testPaper.getCreateMode().equals("random")) {
            List<EduRandomSelectQuestionConfig> configs = JSONArray.parseArray(testPaper.getCreateConfig(), EduRandomSelectQuestionConfig.class);
            for (EduRandomSelectQuestionConfig config : configs) {
                if (config.getQuestionType().equals(DistributionQuestionTypes.ZG_CHOICE.getCode()) ||
                        config.getQuestionType().equals(DistributionQuestionTypes.RANDOM_CONTAIN_ZG_CHOICE.getCode())) {
                    isZg = true;
                    break;
                }
            }
        } else {
            List<EduTestPaperQuestion> paperQuestion = eduTestPaperQuestionService.findByPaperId(testPaper.getId());
            for (EduTestPaperQuestion eduTestPaperQuestion : paperQuestion) {
                EduQuestion eduQuestion = eduQuestionDao.getOne(eduTestPaperQuestion.getQuestionId());
                if (eduQuestion.getType().equals(QuestionTypes.ZG_CHOICE.getCode())) {
                    isZg = true;
                    break;
                }
            }
        }

        return isZg;
    }

    @Override
    public void delete(Long id) throws BusinessRestrictionsException {
        EduTestPaper paper = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("试卷不存在"));
        // 校验业务逻辑是否允许删除。如本数据被其他业务关联，删除后导致其他业务不可用。不能删除时将抛出业务异常
        checkBussinessRestrictions(id);
        // 删除本试卷下试题的关联关系
        eduTestPaperQuestionDao.deleteByTestPaperId(id);
        dao.deleteById(id);
        // 更改试卷类型数量
        commonTypeService.updateTypeCount(CommonTypes.TEST_PAPER, paper.getTypeId());
    }

    /**
     * 校验业务逻辑是否允许删除。如本数据被其他业务关联，删除后导致其他业务不可用
     *
     * @param id 要删除的业务ID
     */
    private void checkBussinessRestrictions(Long id) throws BusinessRestrictionsException {
        Assert.isTrue(dao.countOfExam(id) == 0, "试卷已关联考试，不可以删除");
    }

    @Override
    public EduTestPaper findById(Long id) {
        return dao.findById(id).orElse(null);
    }

    @Override
    public EduTestPaperDetailBean getById(Long id, Long userId) {
        EduTestPaper entity = findById(id);
        if (entity == null) {
            return null;
        }
        EduTestPaperDetailBean bean = new EduTestPaperDetailBean();
        BeanUtils.copyProperties(entity, bean);
        bean.setTypeName(commonTypeService.getNameById(entity.getTypeId()));
        if (!isRandomMode(entity.getCreateMode())) {
            // 非随机模式，查询试题
            bean.setQuestions(findQuestionsOfTestPaper(id, false, false, userId));
        }
        if (entity.getCreateConfig() != null) {
            bean.setConfigs(
                    new Gson().fromJson(entity.getCreateConfig(), new TypeToken<List<EduRandomSelectQuestionConfig>>() {
                    }.getType()));
        }
        return bean;
    }

    private List<EduTestPaperQuestionDetailBean> findQuestionsOfTestPaper(Long id, boolean needQuestionTypeName,
                                                                          boolean needAnswer, Long userId) {
        EduTestPaper paper = eduTestPaperDao.findById(id).get();
        List<EduTestPaperQuestion> list = new ArrayList<>();
        if (!isRandomMode(paper.getCreateMode())) {
            list = eduTestPaperQuestionDao.findByTestPaperIdOrderByIndexNoAsc(id);
        } else {
            list = eduTestPaperQuestionDao.findByTestPaperIdAndUserIdOrderByIndexNoAsc(id, userId);
        }

        return list.stream().map(e -> this.convertQuestion(e, needQuestionTypeName, needAnswer))
                .collect(Collectors.toList());
    }


    private List<EduTestPaperQuestionDetailBean> findNewQuestionsOfTestPaper(Long id, boolean needQuestionTypeName,
                                                                             boolean needAnswer, Long userId, Long examId, List<Long> testPaperQuestionIds) {
        EduTestPaper paper = eduTestPaperDao.findById(id).get();
        List<EduTestPaperQuestion> list;
        if (CollectionUtils.isNotEmpty(testPaperQuestionIds)) {
            list = eduTestPaperQuestionDao.findByIdList(testPaperQuestionIds);
        } else {
            if (!isRandomMode(paper.getCreateMode())) {
                list = eduTestPaperQuestionDao.findByTestPaperIdOrderByIndexNoAsc(id);
            } else {
                list = eduTestPaperQuestionDao.findByTestPaperIdAndUserIdAndExamIdOrderByIndexNoAsc(id, userId, examId);
                if (CollectionUtils.isEmpty(list)) {
                    list = eduTestPaperQuestionDao.findByTestPaperIdAndUserIdOrderByIndexNoAsc(id, userId);
                }
            }
        }
        return list.stream().map(e -> this.convertQuestion(e, needQuestionTypeName, needAnswer))
                .collect(Collectors.toList());
    }

    private EduTestPaperQuestionDetailBean convertQuestion(EduTestPaperQuestion q, boolean needQuestionTypeName,
                                                           boolean needAnswer) {
        EduTestPaperQuestionDetailBean bean = new EduTestPaperQuestionDetailBean();
        bean.setId(q.getId());
        bean.setScore(q.getScore());

        questionDao.findById(q.getQuestionId()).ifPresent(question -> {
            bean.setQuestionId(question.getId());
            bean.setContent(question.getContent());
            bean.setName(question.getName());
            bean.setTypeName(QuestionTypes.findNameByCode(question.getType()));
            bean.setType(question.getType());
            if (needQuestionTypeName) {
                CommonType t = commonTypeService.findById(question.getQuestionTypeId());
                if (t != null) {
                    bean.setQuestionTypeName(t.getName());
                }
            }
            if (needAnswer) {
                bean.setAnswer(question.getAnswer());
            }
        });
        return bean;
    }

    @Override
    public List<EduRandomSelectQuestionBean> randomSelectQuestions(Long testPaperId,
                                                                   List<EduRandomSelectQuestionConfig> configs) {
        if (testPaperId != null) {
            long count = eduExamTestPaperDao.count(QEduExamTestPaper.eduExamTestPaper.testPaperId.eq(testPaperId));
            if (count > 0) {
                throw new IllegalArgumentException("试卷已发布，不能再随机变更题目");
            }
        }
        return questionService.randomSelectAndConvert(configs);
    }

    @Override
    public List<EduTestPaperQuestionDetailBean> getQuestionList(Long id, Long userId) {
        return findQuestionsOfTestPaper(id, true, true, userId);
    }

    @Override
    public void validateConfigRules(List<EduRandomSelectQuestionConfig> configs) {
        if (configs != null && configs.size() > 0) {
            configs.forEach((item) -> {
                Assert.isTrue(item.getQuestionCount() > 0, String.format("题量必须大于0:%s", QuestionTypes.findNameByCode(item.getQuestionType())));
                Assert.isTrue(item.getScore() > 0, "分数必须大于0");
            });
        }
        List<String> configList = new ArrayList<>(configs.size());
        for (EduRandomSelectQuestionConfig c : configs) {
            String key = c.getCatagory() + "_" + c.getQuestionType();
            if (configList.contains(key)) {
                throw new IllegalArgumentException("配置中包含有重复项，请去重后重新提交");
            }
            configList.add(key);
        }
    }

    @Override
    public EduTestPaper findByExamId(Long examId) {
        EduTestPaper paper = eduTestPaperDao.findByExamId(examId);
        return paper;
    }

    @Override
    public List<EduTestPaperQuestionDetailBean> getQuestionList(Long id, boolean includeItems, Long userId) {

        List<EduTestPaperQuestionDetailBean> questionList = findQuestionsOfTestPaper(id, true, true, userId);
        if (includeItems) {
            questionList.forEach(question -> {
                List<EduQuestionItem> choiceList = questionItemDao.findByQuestionIdOrderByIndexNoAsc(question.getQuestionId());
                // web展示的选项
                question.setChoices(choiceList.stream()
                        .map(choice -> choice.getChoiceCode() + Constant.SPLIT_STOP + choice.getContent()).collect(Collectors.toList()));
                // app展示的选项
                question.setChoiceList(choiceList.stream()
                        .map(choice -> new EduTestPaperQuestionDetailBean.Choices(choice.getChoiceCode(), choice.getContent())).collect(Collectors.toList()));
            });
        }
        return questionList;
    }

    @Override
    public List<EduTestPaperQuestionDetailBean> getQuestionList(Long id, boolean includeItems, Long userId, Long examId, List<Long> testPaperQuestionIds) {

        List<EduTestPaperQuestionDetailBean> questionList = findNewQuestionsOfTestPaper(id, true, true, userId, examId, testPaperQuestionIds);
        if (includeItems) {
            questionList.forEach(question -> {
                List<EduQuestionItem> choiceList = questionItemDao.findByQuestionIdOrderByIndexNoAsc(question.getQuestionId());
                // web展示的选项
                question.setChoices(choiceList.stream()
                        .map(choice -> choice.getChoiceCode() + Constant.SPLIT_STOP + choice.getContent()).collect(Collectors.toList()));
                // app展示的选项
                question.setChoiceList(choiceList.stream()
                        .map(choice -> new EduTestPaperQuestionDetailBean.Choices(choice.getChoiceCode(), choice.getContent())).collect(Collectors.toList()));
            });
        }
        return questionList;
    }

    @SneakyThrows
    @Override
    @org.springframework.transaction.annotation.Transactional(propagation= Propagation.NOT_SUPPORTED)
    public void paperExcel(Long id, Integer type, HttpServletResponse response) {
        Word07Writer word07Writer = new Word07Writer();
        EduTestPaper one = eduTestPaperDao.getOne(id);
        word07Writer.addText(ParagraphAlignment.CENTER, new Font("宋体", Font.PLAIN, 16), one.getName() + "考试");
        word07Writer.addText(ParagraphAlignment.CENTER, new Font("宋体", Font.PLAIN, (int) 10.5f), "总分：" + one.getTotalScore() + "分 " + "及格分数：" + one.getPassScore() + "分");
        word07Writer.addText(new Font("宋体", Font.PLAIN, (int) 10.5f), "");
         List<EduQuestionConfigDto> eduQuestions = new ArrayList<>();
        if (one.getCreateMode().equals("random")){
            List<EduRandomSelectQuestionConfig> configs = JSONArray.parseArray(one.getCreateConfig(), EduRandomSelectQuestionConfig.class);
            List<EduQuestionServiceImpl.QuestionSelectWrapper> wrappers = questionService.randomSelectWrapper(configs);
            for (EduQuestionServiceImpl.QuestionSelectWrapper questionSelectWrapper : wrappers){
                EduQuestionConfigDto questionConfigDto = new  EduQuestionConfigDto();
                BeanUtils.copyProperties(questionSelectWrapper.q,questionConfigDto);
                questionConfigDto.setScore(String.valueOf(questionSelectWrapper.config.getScore()));
                eduQuestions.add(questionConfigDto);
            }
        }else {
            eduQuestions = eduTestPaperMapper.selectQuestion(id);
        }
        List<EduQuestionConfigDto> radioList = eduQuestions.stream().filter(item -> item.getType().equals("S")).collect(Collectors.toList());
        List<EduQuestionConfigDto> multiList = eduQuestions.stream().filter(item -> item.getType().equals("M")).collect(Collectors.toList());
        List<EduQuestionConfigDto> judgeList = eduQuestions.stream().filter(item -> item.getType().equals("J")).collect(Collectors.toList());
        List<EduQuestionConfigDto> ZList = eduQuestions.stream().filter(item -> item.getType().equals("Z")).collect(Collectors.toList());
        getWordType(id, type, word07Writer, radioList);
        getWordType(id, type, word07Writer, multiList);
        getWordType(id, type, word07Writer, judgeList);
        getWordType(id, type, word07Writer, ZList);
        response.setContentType("application/msword");
        // 告诉浏览器，当前响应数据要求用户干预保存到文件中，以及文件名是什么 如果文件名有中文，必须URL编码
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(one.getName() + ".doc", "UTF-8"));
        response.setCharacterEncoding("utf-8");
        ServletOutputStream outputStream = response.getOutputStream();
        //word07Writer.flush(FileUtil.file("C:\\Users\\detong\\Desktop\\" + URLEncoder.encode(Math.round(Math.random() * 100)+ one.getName() + ".doc");
        word07Writer.flush(outputStream);
        word07Writer.close();
    }


    private void getWordType(Long id, Integer type, Word07Writer word07Writer, List<EduQuestionConfigDto> list) {
        Integer count = 1;
        for (EduQuestionConfigDto paperQuDTO : list) {
            if (paperQuDTO.getType().equals("Z")) {
                paperQuDTO.setType("主观题");
            }
            if (paperQuDTO.getType().equals("S")) {
                paperQuDTO.setType("单选题");
            }
            if (paperQuDTO.getType().equals("M")) {
                paperQuDTO.setType("多选题");
            }
            if (paperQuDTO.getType().equals("J")) {
                paperQuDTO.setType("判断题");
                if (paperQuDTO.getAnswer().equals("是")){
                paperQuDTO.setAnswer("A");
                }
                if (paperQuDTO.getAnswer().equals("否")){
                paperQuDTO.setAnswer("B");
                }
            }
            if (paperQuDTO.getScore() != null){
                            word07Writer.addText(new Font("宋体", Font.PLAIN, (int) 10.5f),
                    (count++) + ". " + " 【" + paperQuDTO.getType() + "】 " + paperQuDTO.getName() + "（" + (paperQuDTO.getScore()) + "分）");
            }else {
                 EduTestPaperQuestion testPaper = eduTestPaperMapper.selectByquestionId(id, paperQuDTO.getId());
                 word07Writer.addText(new Font("宋体", Font.PLAIN, (int) 10.5f),
                    (count++) + ". " + " 【" + paperQuDTO.getType() + "】 " + paperQuDTO.getName() + "（" + (testPaper.getScore()) + "分）");
            }
            List<EduQuestionItem> quAnswerDTOList = questionItemDao.getByItem(paperQuDTO.getId());
            if (paperQuDTO.getType().equals("主观题")) {
                for (int i = 1; i <= 10; i++) {
                    word07Writer.addText(new Font("宋体", Font.PLAIN, (int) 10.5f), "");
                }
            } else {
                for (EduQuestionItem quAnswerDTO : quAnswerDTOList) {
                    if (quAnswerDTO.getChoiceCode().equals("是")){
                    quAnswerDTO.setChoiceCode("A");
                    }
                    if (quAnswerDTO.getChoiceCode().equals("否")){
                    quAnswerDTO.setChoiceCode("B");
                    }
                    word07Writer.addText(new Font("宋体", Font.PLAIN, (int) 10.5f),
                            quAnswerDTO.getChoiceCode() + "、" + quAnswerDTO.getContent());
                }
            }
            // 7、得到答案并保存到文件中
            if (type == 1) {
                word07Writer.addText(new Font("宋体", Font.BOLD, (int) 10.5f), "答案：" + paperQuDTO.getAnswer());
            }
               word07Writer.addText(new Font("宋体", Font.PLAIN, (int) 10.5f), "");
        }
    }
}
